package com.ruoyi.app.config.interceptor;

import com.ruoyi.app.config.annotation.OperationAuth;
import com.ruoyi.app.config.annotation.SysMangerAuth;
import com.ruoyi.app.config.util.UserUtil;
import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.enums.YesNoEnum;
import com.ruoyi.common.core.exception.UserAuthException;
import com.ruoyi.common.core.utils.CommonUtils;
import com.ruoyi.common.core.utils.pwd.PwdUtil;
import com.ruoyi.service.company.enums.CheckStatusEnum;
import com.ruoyi.service.user.enums.UserTypeEnum;
import com.ruoyi.service.user.model.UserInfoModel;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nonnull;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * <p>
 * 作用：项目方操作拦截器
 * </p>
 *
 * @author Zane
 * @since 2025-10-05 23:20
 */
@Slf4j
@Component
@RefreshScope
public class OperationAuthInterceptor implements HandlerInterceptor {

  @Override
  public boolean preHandle(@Nonnull HttpServletRequest request,
      @Nonnull HttpServletResponse response, @Nonnull Object handler) throws Exception {
    // 检查handler是否是HandlerMethod的实例
    if (!(handler instanceof HandlerMethod)) {
      // 如果不是HandlerMethod的实例，则直接返回true，允许请求继续
      return true;
    }
    final HandlerMethod handlerMethod = (HandlerMethod) handler;
    //优先判断是否系统管理员,只针某些特殊特接口
    checkSysAuth(request, handlerMethod);
    final OperationAuth operationAuth =
        Optional.ofNullable(handlerMethod.getMethodAnnotation(OperationAuth.class))
            .orElseGet(() -> handlerMethod.getBeanType().getAnnotation(OperationAuth.class));
    if (operationAuth == null || operationAuth.value().length == 0) {
      return true;
    }
    final UserInfoModel loginUser = UserUtil.getLoginUser();
    if (UserTypeEnum.DEMANDER_USER.eq(loginUser.getUserType())
        && operationAuth.demanderHasCompanyCheck()
        && Objects.isNull(loginUser.getCompanyId())) {
      //项目方需要补全公司信息
      throw new UserAuthException(HttpStatus.LIMIT, "请先完善项目方公司信息,并审核通过");
    }
    //校验劳务方是否被封号
    if (UserTypeEnum.LABOR_USER.eq(loginUser.getUserType())
        && operationAuth.laborHasBanedCheck()
        && YesNoEnum.isTrue(loginUser.getBanFlag())) {
      throw new UserAuthException(HttpStatus.WARN, "您的账户已经被封禁,请联系管理员");
    }
    //校验角色权限
    if (Arrays.stream(operationAuth.value())
        .noneMatch(userTypeEnum -> userTypeEnum.eq(loginUser.getUserType()))) {
      throw new UserAuthException(HttpStatus.WARN, "登录用户不具有操作权限,请联系管理员");
    }
    //项目方公司未审核 通过
    if (UserTypeEnum.DEMANDER_USER.eq(loginUser.getUserType())
        && !CheckStatusEnum.isPassed(loginUser.getCompanyStatus())) {
      //校验公司是否很恶化通过
      if (operationAuth.demanderCompanyPassedCheck()) {
        throw new UserAuthException(HttpStatus.WARN, "公司信息未审核通过,操作受限,请联系管理员");
      }
    }
    return true;
  }

  @Value("${kp.manager.key:ef6a234e03b159f51f171df42aad08dc}")
  private String managerKey;

  private void checkSysAuth(HttpServletRequest request, HandlerMethod handlerMethod) {
    final SysMangerAuth sysAuth =
        Optional.ofNullable(handlerMethod.getMethodAnnotation(SysMangerAuth.class))
            .orElseGet(() -> handlerMethod.getBeanType().getAnnotation(SysMangerAuth.class));
    if (sysAuth == null) {
      return;
    }
    final String managerEncodeKey = request.getHeader(SecurityConstants.HEADER_MANAGER_KEY);
    CommonUtils.requireNotNull(managerEncodeKey, "接口访问被拒绝");
    //校验密钥
    if (!managerEncodeKey.equals(PwdUtil.encode(managerKey))) {
      throw new UserAuthException(HttpStatus.WARN, "接口访问被拒绝");
    }
  }

}
